import router from "@/router";

let BASE_URL = `http://${window.location.host}/api`;

if (import.meta.env.MODE === 'development') {
    // 在开发模式下的逻辑
    BASE_URL = "http://localhost:5173/api";
}

const SESSION_KEY_HEAD = "session_key";

const HEAD_RESP_KEY = "resp";
const RESP_OK = "ok";
const RESO_ERR = "err";

let sessionKey = '';

function initSessionKey() {
    const v = window.localStorage.getItem(SESSION_KEY_HEAD);
    if (v != null) {
        sessionKey = v;
    }
}

function saveSessionKey() {
    window.localStorage.setItem(SESSION_KEY_HEAD, sessionKey);
}

initSessionKey();

interface ErrInfo {
    err_code: number,
    err_msg: string,
}

const CONTENT_TYPE_JSON: [string, string] = ["Content-Type", "application/json"];

function joinUrl(url: string) {
    return `${BASE_URL}${url}`
}

async function respCheck(resp: Response) {
    if (resp.status != 200) {
        throw resp.statusText;
    }
    const r = resp.headers.get(HEAD_RESP_KEY)
    if (r == null) {
        throw '无法处理的返回';
    }
    if (r != RESP_OK) {
        const errInfo = await resp.json() as ErrInfo;
        if (errInfo.err_msg == "没有登陆") {
            router.push('/');
        }
        throw `错误码:${errInfo.err_code} 错误信息:${errInfo.err_msg}`;
    }
}

async function httpPostJson<R, T>(url: string, body: T) {
    const resp = await fetch(joinUrl(url), {
        method: 'POST',
        body: JSON.stringify(body),
        headers: [[SESSION_KEY_HEAD, sessionKey], CONTENT_TYPE_JSON]
    });
    await respCheck(resp);
    return await resp.json() as R;
}

async function httpPostJson2<T>(url: string, body: T) {
    const resp = await fetch(joinUrl(url), {
        method: 'POST',
        body: JSON.stringify(body),
        headers: [[SESSION_KEY_HEAD, sessionKey], CONTENT_TYPE_JSON]
    });
    await respCheck(resp);
}

async function httpGetJson<R>(url: string) {
    const resp = await fetch(joinUrl(url), {
        method: 'GET',
        headers: [[SESSION_KEY_HEAD, sessionKey], CONTENT_TYPE_JSON]
    });
    await respCheck(resp);
    return await resp.json() as R;
}

async function httpPostForm<R>(url: string, form: FormData) {
    const resp = await fetch(joinUrl(url), {
        method: 'POST',
        body: form,
        headers: [[SESSION_KEY_HEAD, sessionKey]]
    });
    await respCheck(resp);
    return await resp.json() as R;
}

export interface LoginReq {
    account: string,
    pwd: string,
}

export interface Perm {
    type_code: number,
    type_msg: string,
}

export interface UserInfo {
    id: number,
    account: string,
    pwd: string,
    name: string,
}

export interface SessionInfo {
    user: UserInfo,
    perms: Perm[],
    login_invalid_timestamp: number,
}

export interface EmplInfo2 {
    account: string,
    name: string,
    org: string,
    job: string,
    date: string,
    holiday: number,
    active: number,
}

export interface Holiday {
    type_info: string,
    days: number,
    begin: string,
    end: string,
    version: number,
}

export interface HolidayInfo {
    empl: EmplInfo2,
    details: Holiday[],
}

export interface LoginRes {
    session: SessionInfo,
    key: string,
}

export const VERSION_BEFORE = 0;
export const VERSION_AFTER = 1;
export const VERSION_ALL = 2;

export interface HolidayPartInfo {
    begin_date: string,
    end_date: string,
    days: number,
    description: string,
    version: number,
}

export interface ServicePartInfo {
    holiday: HolidayPartInfo,
    leaves: LeaveInfo[],
    leave_days: number,
    days: number,
}

export interface HolidayYearInfo {
    current_holiday: ServicePartInfo | null,
    holiday_parts: ServicePartInfo[],
}

export interface Service2Req {
    account: string,
    now_date: string,
}

export interface ServiceYearCalcRes {
    empl: EmplInfo2,
    holiday: HolidayYearInfo,
}

export interface ServiceCurrentCalcRes {
    empl: EmplInfo2,
    holiday: ServicePartInfo | null,
}

export interface ServiceOrgReq {
    org_name: string,
    now_date: string,
}

export interface ServiceAllReq {
    now_date: string,
}

export const service = {

    async calcAllYearHoliday(req: ServiceAllReq) {
        return await httpPostJson<ServiceYearCalcRes[], ServiceAllReq>('/service2/calc/all/year', req);
    },

    async calcOrgYearHoliday(req: ServiceOrgReq) {
        return await httpPostJson<ServiceYearCalcRes[], ServiceOrgReq>('/service2/calc/org/year', req);
    },

    async calcYearHoliday(req: Service2Req) {
        let url = '/service2/calc/year';
        return await httpPostJson<ServiceYearCalcRes, Service2Req>(url, req);
    },

    async calcCurrentHoliday(req: Service2Req) {
        let url = '/service2/calc/current';
        return await httpPostJson<ServiceCurrentCalcRes, Service2Req>(url, req);
    },

    async login(req: LoginReq) {
        const info = await httpPostJson<LoginRes, LoginReq>('/user/login', req);
        sessionKey = info.key;
        saveSessionKey();
        return info;
    },

    async selectOrgs() {
        const orgs = await httpGetJson<string[]>('/empl/select/orgs');
        return orgs;
    },

    async selectEmpls(orgName: string) {
        interface Ctx {
            name: string
        };
        const empls = await httpPostJson<EmplInfo2[], Ctx>('/empl/select/org/empl', { name: orgName });
        return empls;
    },

    async emplHoliday(account: string) {
        const url = `/holiday/empl?account=${account}`;
        return await httpGetJson<HolidayInfo>(url);
    },

    async upload_empl_excel(file: File) {
        const form = new FormData();
        form.append('file', file);
        const count = httpPostForm<number>('/empl/upload/excel', form);
        return count;
    },

    async createLeave(req: LeaveCreateReq) {
        const url = '/leave/create';
        await httpPostJson2<LeaveCreateReq>(url, req);
    },

    async selectLeave(req: LeaveSelectReq) {
        const url = `/leave/select?account=${req.account}&year=${req.year}`;
        const resp = await httpGetJson<LeaveInfo[]>(url);
        return resp;
    },

    async deleteLeave(req: LeaveDeleteReq) {
        await httpPostJson2<LeaveDeleteReq>('/leave/delete', req);
    },

    async calcHoliday(req: HolidayCalcReq) {
        const url = `/service/calc?account=${req.account}&year=${req.year}`;
        return await httpGetJson<CalcRes>(url);
    },

    async createEmpl(empl: EmplInfo2) {
        await httpPostJson2<EmplInfo2>('/empl/create', empl);
    },

    async changeEmpl(empl: EmplInfo2) {
        await httpPostJson2<EmplInfo2>('/empl/create', empl);
    },

    async activeEmpl(req: ActiveEmplReq) {
        await httpPostJson2<ActiveEmplReq>('/empl/change/active', req);
    }
};

export interface ActiveEmplReq {
    account: string,
    active: number,
}

export interface LeaveCreateReq {
    account: string,
    date: string,
    time: number,
    days: number,
}

export interface LeaveSelectReq {
    account: string,
    year: number,
}

export interface LeaveInfo {
    id: number,
    account: string,
    date: string,
    time: number,
    days: number,
    version: number,
}

export interface LeaveDeleteReq {
    id: number,
}

export interface HolidayCalcReq {
    account: string,
    year: number,
}

export interface CalcRes {
    empl: EmplInfo2,
    days: number,
    holidays: Holiday[],
    leaves: LeaveInfo[],
}


